Data structures
'GameController' *Center piece of the scripts. *Is a singleton attached to GameController prefab in the PersistentScene scene. *Singleton is accessed via GameController.Instance; *'Stores references' to objects other scripts might need. *These references are accessible via the class'es properties. These are read-only. **''ie: GameController.Instance.PlayerController.Heal(0.25f);'' *GameController calls each eligible reference'es Init() methods in it's Start() method. This allows precise control over initialization order. *'References '''stored in the instance '''must be initialized' via it's SetReference() method. The method is to be called on Awake() in the script of the object you wish to store a reference to. **''ie: Setting the reference to PlayerController and initializing it.'' **''Program starts. =>'' **''PlayerController's Awake() is called. =>'' **''PlayerController requests it's reference to be set in the GameController. =>'' **''GameController sets it's reference. =>'' **''Time passes. =>'' **''GameController's Start() is called. =>'' **''GameController calls the Init() of PlayerController.'' *'public bool SetReference(Monobehaviour caller)' returns true if the reference has been successfully set, false if it encoutered an issue. Use this to throw errors. 'EventManager' *Centralizes all causality relationships, improving modularity. *Attached to GameController prefab in the PersistentScene scene. *Accessed via the GameController. **''ie: GameController.Instance.EventHandler;'' *'Defines custom events'. Each new event type needs three things to be defined: **An enum value in EventType enum. **A delegate type from which to make an event from. **An event created from the delegate type publicly accessible to store callbacks in. *Events are triggered via TriggerEvent(). **''ie: Sending a stepped in fire event: GameController.Instance.EventHandler.AddEvent(EventType.STEPPED_IN_FIRE);'' *'Callbacks '''are to be added to the instance'es '''public event attributes'. They all begin with "On". **''ie: GameController.Instance.OnDeath += DisplayGameOver;'' *Use example: Tutorial teaching the player to move: **Text showing movement controls is displayed. => **Player presses the move button => **InputHandler detects input and creates a MOVE event via AddEvent(). => **InputHandler invokes all callbacks stored in OnMove. => **PlayerController's Move() callback is invoked AND TutorialController's Move() callback is invoked. => **PlayerController's Move() calls PlayerMovementController's Move() AND PlayerAnimationController's Move(). **At the same time TutorialController's Move() callback changes tutorial's stage from AWAITING_INPUT to TRANSITION_TO_NEXT_STAGE. 'InputManager' *Centralizes all inputs, improving modularity. *Attached to GameController prefab in the PersistentScene scene. *'Sends input messages' to concerned scripts via the EventManager. **''ie: Jump button'' **''Player presses the jump button. =>'' **''InputManager detects it and sends a JUMP event. =>'' **''PlayerController recieves the event and calls it's Jump() private function.'' *Has three operating states: **GAME: Applies main game's control scheme. **MENU: Applies the menu's control scheme. ***ie: ENTER to press menu button, UP_ARROW to select button above, etc. **CUTSCENE: Applies the cutscene's control scheme. ***ie: ESC to skip the cutscene. 'SceneManager' *Manages scene transitions. *There is one PersistentScene in the game. It has the Main Camera and the GameController prefab. *'Scene transitions' in this game are done additively 'as to avoid loading times. *'LoadSceneAsync() and UnloadSceneAsync() are used to transition between scenes seamlessly. They send events on loading/unloading start and end. 'CameraController' *Controlls the movements of the camera. *Attached to MainCamera GameObject in the PersistentScene scene. *Has three operating modes: **GAME: Relays control of the camera to the Cinemachine script. **MENU: Camera is static. **CUTSCENE: The camera traverses the Cutscene sequence. 'PlayerController' *Controller class interfacing with the rest of the game's system. *'Gets objects needed' by player's components and initializes the components when it's Init() function is called by the GameController on Start(). *'Calls' player component's appropriate public methods upon various events. **''ie: Player's jump'' **''PlayerController's Init() function is called by GameController. =>'' **''Init() adds Jump() callback to GameController.EventHandler.OnJump event.'' **''Some time passes =>'' **''PlayerController's Jump() function is invoked by the EventHandler.'' **''Jump() calls PlayerMovementComponent's Jump() function AND PlayerAnimationComponent's Jump() function.'' 'PlayerMovementComponent' *Controls only the movement physics of the player. This includes: **Walking and Running **Jumping **Swinging on gum *Requests input data upon reception of an input event from the InputHandler. **''ie: Moving player to the right.'' **''PlayerMovementController recieves a HORIZONTAL_INPUT event. =>'' **''PlayerMovementController updates it's _horizontalInput variable and waits. =>'' **''Some time passes. =>'' **''FixedUpdate is called. =>'' **''PlayerMovemementController applies a force to the player's rigidbody using _horizontalInput variable.'' Diagrams * Composition Diagram: * Script Initialization Order:''